#ifndef COMMAND_H
#define COMMAND_H

#include <string>
#include <memory>
#include <optional>
#include "TaskManager.h"
#include "Logger.h"

class TaskManager;

/**
 * @brief 命令接口基类 (使用CRTP模式)
 * 
 * @tparam Derived 派生类类型
 */
template <typename Derived>
class Command {
public:
    virtual ~Command() = default;
    
    /**
     * @brief 执行命令
     * @param manager 任务管理器
     * @return std::string 命令执行结果
     */
    std::string execute(TaskManager& manager) {
        return static_cast<Derived*>(this)->executeImpl(manager);
    }
};

/**
 * @brief 添加任务命令
 */
class AddTaskCommand : public Command<AddTaskCommand> {
public:
    /**
     * @brief 构造函数
     * @param description 任务描述
     * @param priority 任务优先级
     * @param dueDate 截止日期
     */
    AddTaskCommand(const std::string& description, Priority priority, const std::string& dueDate);
    
    std::string executeImpl(TaskManager& manager);
    
private:
    std::string description;
    Priority priority;
    std::string dueDate;
};

/**
 * @brief 删除任务命令
 */
class DeleteTaskCommand : public Command<DeleteTaskCommand> {
public:
    /**
     * @brief 构造函数
     * @param id 要删除的任务ID
     */
    explicit DeleteTaskCommand(int id);
    
    std::string executeImpl(TaskManager& manager);
    
private:
    int id;
};

/**
 * @brief 查看任务命令
 */
class ListTasksCommand : public Command<ListTasksCommand> {
public:
    /**
     * @brief 构造函数
     * @param sortBy 排序方式 ("priority" 或 "date")
     */
    explicit ListTasksCommand(const std::string& sortBy = "");
    
    std::string executeImpl(TaskManager& manager);
    
private:
    std::string sortBy;
};

/**
 * @brief 更新任务命令
 */
class UpdateTaskCommand : public Command<UpdateTaskCommand> {
public:
    ~UpdateTaskCommand() noexcept override = default;  // 显式声明 noexcept

    /**
     * @brief 构造函数
     * @param id 任务ID
     * @param description 新描述 (空表示不更新)
     * @param priority 新优先级 (nullopt表示不更新)
     * @param dueDate 新截止日期 (空表示不更新)
     */
    UpdateTaskCommand(int id, const std::string& description, 
                     std::optional<Priority> priority, const std::string& dueDate);
    
    std::string executeImpl(TaskManager& manager);
    
private:
    int id;
    std::string description;
    std::optional<Priority> priority;
    std::string dueDate;
};

#endif // COMMAND_H